﻿namespace UnityEditor
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using UnityEditorInternal;
    using UnityEngine;

    internal class NavMeshEditorWindow : EditorWindow, ICanHazCustomMenu
    {
        [CompilerGenerated]
        private static Func<GameObject, bool> <>f__am$cache10;
        private const string kRootPath = "m_BuildSettings.";
        private SerializedProperty m_AccuratePlacement;
        private bool m_Advanced;
        private SerializedProperty m_AgentClimb;
        private SerializedProperty m_AgentHeight;
        private SerializedProperty m_AgentRadius;
        private SerializedProperty m_AgentSlope;
        private SerializedProperty m_HeightInaccuracy;
        private SerializedProperty m_LedgeDropHeight;
        private SerializedProperty m_MaxJumpAcrossDistance;
        private SerializedProperty m_MinRegionArea;
        private Mode m_Mode;
        private SerializedObject m_Object;
        private Vector2 m_ScrollPos = Vector2.zero;
        private SerializedProperty m_WidthInaccuracy;
        private static NavMeshEditorWindow s_MsNavMeshEditorWindow;
        private static Styles s_Styles;

        public virtual void AddItemsToMenu(GenericMenu menu)
        {
        }

        public static void BackgroundTaskStatusChanged()
        {
            if (s_MsNavMeshEditorWindow != null)
            {
                s_MsNavMeshEditorWindow.Repaint();
            }
        }

        private static void BakeButtons()
        {
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            GUILayout.FlexibleSpace();
            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Width(95f) };
            if (GUILayout.Button("Reset", options))
            {
                Unsupported.SmartReset(NavMeshBuilder.navMeshSettingsObject);
            }
            bool enabled = GUI.enabled;
            GUI.enabled &= !Application.isPlaying;
            GUILayoutOption[] optionArray2 = new GUILayoutOption[] { GUILayout.Width(95f) };
            if (GUILayout.Button("Clear", optionArray2))
            {
                NavMeshBuilder.ClearAllNavMeshes();
            }
            GUI.enabled = enabled;
            if (NavMeshBuilder.isRunning)
            {
                GUILayoutOption[] optionArray3 = new GUILayoutOption[] { GUILayout.Width(95f) };
                if (GUILayout.Button("Cancel", optionArray3))
                {
                    NavMeshBuilder.Cancel();
                }
            }
            else
            {
                enabled = GUI.enabled;
                GUI.enabled &= !Application.isPlaying;
                GUILayoutOption[] optionArray4 = new GUILayoutOption[] { GUILayout.Width(95f) };
                if (GUILayout.Button("Bake", optionArray4))
                {
                    NavMeshBuilder.BuildNavMeshAsync();
                }
                GUI.enabled = enabled;
            }
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
        }

        private void BakeSettings()
        {
            EditorGUILayout.LabelField(s_Styles.m_GeneralHeader, EditorStyles.boldLabel, new GUILayoutOption[0]);
            float num = EditorGUILayout.FloatField(s_Styles.m_AgentRadiusContent, this.m_AgentRadius.floatValue, new GUILayoutOption[0]);
            if ((num >= 0.001f) && !Mathf.Approximately(num - this.m_AgentRadius.floatValue, 0f))
            {
                this.m_AgentRadius.floatValue = num;
            }
            float num2 = EditorGUILayout.FloatField(s_Styles.m_AgentHeightContent, this.m_AgentHeight.floatValue, new GUILayoutOption[0]);
            if ((num2 >= 0.001f) && !Mathf.Approximately(num2 - this.m_AgentHeight.floatValue, 0f))
            {
                this.m_AgentHeight.floatValue = num2;
            }
            EditorGUILayout.Slider(this.m_AgentSlope, 0f, 90f, s_Styles.m_AgentSlopeContent, new GUILayoutOption[0]);
            float num3 = EditorGUILayout.FloatField(s_Styles.m_AgentClimbContent, this.m_AgentClimb.floatValue, new GUILayoutOption[0]);
            if ((num3 >= 0f) && !Mathf.Approximately(this.m_AgentClimb.floatValue - num3, 0f))
            {
                this.m_AgentClimb.floatValue = num3;
            }
            EditorGUILayout.Space();
            EditorGUILayout.LabelField(s_Styles.m_OffmeshHeader, EditorStyles.boldLabel, new GUILayoutOption[0]);
            float num4 = EditorGUILayout.FloatField(s_Styles.m_AgentDropContent, this.m_LedgeDropHeight.floatValue, new GUILayoutOption[0]);
            if ((num4 >= 0f) && !Mathf.Approximately(num4 - this.m_LedgeDropHeight.floatValue, 0f))
            {
                this.m_LedgeDropHeight.floatValue = num4;
            }
            float num5 = EditorGUILayout.FloatField(s_Styles.m_AgentJumpContent, this.m_MaxJumpAcrossDistance.floatValue, new GUILayoutOption[0]);
            if ((num5 >= 0f) && !Mathf.Approximately(num5 - this.m_MaxJumpAcrossDistance.floatValue, 0f))
            {
                this.m_MaxJumpAcrossDistance.floatValue = num5;
            }
            EditorGUILayout.Space();
            this.m_Advanced = GUILayout.Toggle(this.m_Advanced, s_Styles.m_AdvancedHeader, EditorStyles.foldout, new GUILayoutOption[0]);
            if (this.m_Advanced)
            {
                float num6 = EditorGUILayout.FloatField(s_Styles.m_MinRegionAreaContent, this.m_MinRegionArea.floatValue, new GUILayoutOption[0]);
                if ((num6 >= 0f) && (num6 != this.m_MinRegionArea.floatValue))
                {
                    this.m_MinRegionArea.floatValue = num6;
                }
                EditorGUILayout.Slider(this.m_WidthInaccuracy, 1f, 100f, s_Styles.m_WidthInaccuracyContent, new GUILayoutOption[0]);
                EditorGUILayout.Slider(this.m_HeightInaccuracy, 1f, 100f, s_Styles.m_HeightInaccuracyContent, new GUILayoutOption[0]);
                bool flag = EditorGUILayout.Toggle(s_Styles.m_AgentPlacementContent, this.m_AccuratePlacement.boolValue, new GUILayoutOption[0]);
                if (flag != this.m_AccuratePlacement.boolValue)
                {
                    this.m_AccuratePlacement.boolValue = flag;
                }
            }
        }

        private static void DisplayControls(UnityEngine.Object target, SceneView sceneView)
        {
            EditorGUIUtility.LookLikeControls(110f);
            bool flag = false;
            bool showNavMesh = NavMeshVisualizationSettings.showNavMesh;
            if (showNavMesh != EditorGUILayout.Toggle(EditorGUIUtility.TextContent("NavMeshEditorWindow.ShowNavMesh"), showNavMesh, new GUILayoutOption[0]))
            {
                NavMeshVisualizationSettings.showNavMesh = !showNavMesh;
                flag = true;
            }
            EditorGUI.BeginDisabledGroup(!NavMeshVisualizationSettings.hasHeightMesh);
            bool showHeightMesh = NavMeshVisualizationSettings.showHeightMesh;
            if (showHeightMesh != EditorGUILayout.Toggle(EditorGUIUtility.TextContent("NavMeshEditorWindow.ShowHeightMesh"), showHeightMesh, new GUILayoutOption[0]))
            {
                NavMeshVisualizationSettings.showHeightMesh = !showHeightMesh;
                flag = true;
            }
            EditorGUI.EndDisabledGroup();
            if (flag)
            {
                RepaintSceneAndGameViews();
            }
        }

        private static List<GameObject> GetObjects(bool includeChildren)
        {
            if (!includeChildren)
            {
                return new List<GameObject>(Selection.gameObjects);
            }
            List<GameObject> list = new List<GameObject>();
            foreach (GameObject obj2 in Selection.gameObjects)
            {
                list.AddRange(GetObjectsRecurse(obj2));
            }
            return list;
        }

        private static IEnumerable<GameObject> GetObjectsRecurse(GameObject root)
        {
            List<GameObject> list = new List<GameObject> {
                root
            };
            IEnumerator enumerator = root.transform.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    Transform current = (Transform) enumerator.Current;
                    list.AddRange(GetObjectsRecurse(current.gameObject));
                }
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                if (disposable == null)
                {
                }
                disposable.Dispose();
            }
            return list;
        }

        private void Init()
        {
            this.m_Object = new SerializedObject(NavMeshBuilder.navMeshSettingsObject);
            this.m_AgentRadius = this.m_Object.FindProperty("m_BuildSettings.agentRadius");
            this.m_AgentHeight = this.m_Object.FindProperty("m_BuildSettings.agentHeight");
            this.m_AgentSlope = this.m_Object.FindProperty("m_BuildSettings.agentSlope");
            this.m_LedgeDropHeight = this.m_Object.FindProperty("m_BuildSettings.ledgeDropHeight");
            this.m_AgentClimb = this.m_Object.FindProperty("m_BuildSettings.agentClimb");
            this.m_MaxJumpAcrossDistance = this.m_Object.FindProperty("m_BuildSettings.maxJumpAcrossDistance");
            this.m_AccuratePlacement = this.m_Object.FindProperty("m_BuildSettings.accuratePlacement");
            this.m_MinRegionArea = this.m_Object.FindProperty("m_BuildSettings.minRegionArea");
            this.m_WidthInaccuracy = this.m_Object.FindProperty("m_BuildSettings.widthInaccuracy");
            this.m_HeightInaccuracy = this.m_Object.FindProperty("m_BuildSettings.heightInaccuracy");
        }

        private void ModeToggle()
        {
            this.m_Mode = (Mode) GUILayout.Toolbar((int) this.m_Mode, s_Styles.m_ModeToggles, "LargeButton", new GUILayoutOption[0]);
        }

        private static void ObjectSettings()
        {
            GameObject[] objArray;
            bool flag = true;
            System.Type[] types = new System.Type[] { typeof(MeshRenderer), typeof(Terrain) };
            SceneModeUtility.SearchBar(types);
            EditorGUILayout.Space();
            MeshRenderer[] selectedObjectsOfType = SceneModeUtility.GetSelectedObjectsOfType<MeshRenderer>(out objArray, new System.Type[0]);
            if (objArray.Length > 0)
            {
                flag = false;
                ObjectSettings(selectedObjectsOfType, objArray);
            }
            Terrain[] components = SceneModeUtility.GetSelectedObjectsOfType<Terrain>(out objArray, new System.Type[0]);
            if (objArray.Length > 0)
            {
                flag = false;
                ObjectSettings(components, objArray);
            }
            if (flag)
            {
                GUILayout.Label("Select a MeshRenderer or a Terrain from the scene.", EditorStyles.helpBox, new GUILayoutOption[0]);
            }
        }

        private static void ObjectSettings(UnityEngine.Object[] components, GameObject[] gos)
        {
            bool enabled = GUI.enabled;
            EditorGUILayout.MultiSelectionObjectTitleBar(components);
            SerializedObject obj2 = new SerializedObject(gos);
            if (!SceneModeUtility.StaticFlagField("Navigation Static", obj2.FindProperty("m_StaticEditorFlags"), 8))
            {
                GUI.enabled = false;
            }
            EditorGUILayout.BitToggleField("OffMeshLink Generation", obj2.FindProperty("m_StaticEditorFlags"), 0x20);
            SerializedProperty property = obj2.FindProperty("m_NavMeshLayer");
            EditorGUI.BeginChangeCheck();
            EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
            string[] navMeshLayerNames = GameObjectUtility.GetNavMeshLayerNames();
            int navMeshLayer = GameObjectUtility.GetNavMeshLayer(gos[0]);
            int selectedIndex = -1;
            for (int i = 0; i < navMeshLayerNames.Length; i++)
            {
                if (GameObjectUtility.GetNavMeshLayerFromName(navMeshLayerNames[i]) == navMeshLayer)
                {
                    selectedIndex = i;
                    break;
                }
            }
            int index = EditorGUILayout.Popup("Navigation Layer", selectedIndex, navMeshLayerNames, new GUILayoutOption[0]);
            EditorGUI.showMixedValue = false;
            if (EditorGUI.EndChangeCheck())
            {
                int navMeshLayerFromName = GameObjectUtility.GetNavMeshLayerFromName(navMeshLayerNames[index]);
                property.intValue = navMeshLayerFromName;
                SetNavMeshLayer(navMeshLayerFromName, SelectionHasChildren() && EditorUtility.DisplayDialog("Change Navigation Layer", "Do you want change the navigation layer to " + navMeshLayerNames[index] + " for all the child objects as well?", "Yes, change children", "No, this object only"));
            }
            GUI.enabled = enabled;
        }

        public void OnBecameInvisible()
        {
            NavMeshVisualizationSettings.showNavigation = false;
            SceneView.onSceneGUIDelegate = (SceneView.OnSceneFunc) Delegate.Remove(SceneView.onSceneGUIDelegate, new SceneView.OnSceneFunc(this.OnSceneViewGUI));
            RepaintSceneAndGameViews();
        }

        public void OnBecameVisible()
        {
            if (!NavMeshVisualizationSettings.showNavigation)
            {
                NavMeshVisualizationSettings.showNavigation = true;
                SceneView.onSceneGUIDelegate = (SceneView.OnSceneFunc) Delegate.Combine(SceneView.onSceneGUIDelegate, new SceneView.OnSceneFunc(this.OnSceneViewGUI));
                RepaintSceneAndGameViews();
            }
        }

        public void OnDisable()
        {
            s_MsNavMeshEditorWindow = null;
            EditorApplication.searchChanged = (EditorApplication.CallbackFunction) Delegate.Remove(EditorApplication.searchChanged, new EditorApplication.CallbackFunction(this.Repaint));
        }

        public void OnEnable()
        {
            s_MsNavMeshEditorWindow = this;
            s_Styles = new Styles();
            this.Init();
            EditorApplication.searchChanged = (EditorApplication.CallbackFunction) Delegate.Combine(EditorApplication.searchChanged, new EditorApplication.CallbackFunction(this.Repaint));
            base.Repaint();
        }

        public void OnGUI()
        {
            if (this.m_Object.targetObject == null)
            {
                this.Init();
            }
            this.m_Object.Update();
            EditorGUIUtility.LookLikeControls(130f);
            EditorGUILayout.Space();
            this.ModeToggle();
            EditorGUILayout.Space();
            this.m_ScrollPos = EditorGUILayout.BeginScrollView(this.m_ScrollPos, new GUILayoutOption[0]);
            switch (this.m_Mode)
            {
                case Mode.ObjectSettings:
                    ObjectSettings();
                    break;

                case Mode.BakeSettings:
                    this.BakeSettings();
                    break;
            }
            EditorGUILayout.EndScrollView();
            BakeButtons();
            this.m_Object.ApplyModifiedProperties();
        }

        public void OnSceneViewGUI(SceneView sceneView)
        {
            if (NavMeshVisualizationSettings.showNavigation)
            {
                SceneViewOverlay.Window(new GUIContent("Navmesh Display"), new SceneViewOverlay.WindowFunction(NavMeshEditorWindow.DisplayControls), 300, SceneViewOverlay.WindowDisplayOption.OneWindowPerTarget);
            }
        }

        private void OnSelectionChange()
        {
            this.m_ScrollPos = Vector2.zero;
            if (this.m_Mode == Mode.ObjectSettings)
            {
                base.Repaint();
            }
        }

        private static void RepaintSceneAndGameViews()
        {
            SceneView.RepaintAll();
            foreach (GameView view in Resources.FindObjectsOfTypeAll(typeof(GameView)))
            {
                view.Repaint();
            }
        }

        private static bool SelectionHasChildren()
        {
            if (<>f__am$cache10 == null)
            {
                <>f__am$cache10 = obj => obj.transform.childCount > 0;
            }
            return Enumerable.Any<GameObject>(Selection.gameObjects, <>f__am$cache10);
        }

        private static void SetNavMeshLayer(int layer, bool includeChildren)
        {
            List<GameObject> objects = GetObjects(includeChildren);
            if (objects.Count > 0)
            {
                Undo.RegisterUndo(objects.ToArray(), "Change NavMesh layer");
                foreach (GameObject obj2 in objects)
                {
                    GameObjectUtility.SetNavMeshLayer(obj2, layer);
                }
            }
        }

        [UnityEditor.MenuItem("Window/Navigation", false, 0x834)]
        public static void SetupWindow()
        {
            System.Type[] desiredDockNextTo = new System.Type[] { typeof(InspectorWindow) };
            NavMeshEditorWindow window = EditorWindow.GetWindow<NavMeshEditorWindow>(desiredDockNextTo);
            window.title = EditorGUIUtility.TextContent("NavmeshEditor.WindowTitle").text;
            window.minSize = new Vector2(300f, 360f);
        }

        [UnityEditor.MenuItem("Window/Navigation", true, 0x834)]
        public static bool SetupWindowValidate()
        {
            return InternalEditorUtility.HasPro();
        }

        private enum Mode
        {
            ObjectSettings,
            BakeSettings
        }

        private class Styles
        {
            public readonly GUIContent m_AdvancedHeader = new GUIContent("Advanced");
            public readonly GUIContent m_AgentClimbContent = EditorGUIUtility.TextContent("NavMeshEditorWindow.StepHeight");
            public readonly GUIContent m_AgentDropContent = EditorGUIUtility.TextContent("NavMeshEditorWindow.DropHeight");
            public readonly GUIContent m_AgentHeightContent = EditorGUIUtility.TextContent("NavMeshEditorWindow.Height");
            public readonly GUIContent m_AgentJumpContent = EditorGUIUtility.TextContent("NavMeshEditorWindow.JumpDistance");
            public readonly GUIContent m_AgentPlacementContent = EditorGUIUtility.TextContent("NavMeshEditorWindow.HeightMesh");
            public readonly GUIContent m_AgentRadiusContent = EditorGUIUtility.TextContent("NavMeshEditorWindow.Radius");
            public readonly GUIContent m_AgentSlopeContent = EditorGUIUtility.TextContent("NavMeshEditorWindow.MaxSlope");
            public readonly GUIContent m_GeneralHeader = new GUIContent("General");
            public readonly GUIContent m_HeightInaccuracyContent = EditorGUIUtility.TextContent("NavMeshEditorWindow.HeightInaccuracy");
            public readonly GUIContent m_MinRegionAreaContent = EditorGUIUtility.TextContent("NavMeshEditorWindow.MinRegionArea");
            public readonly GUIContent[] m_ModeToggles = new GUIContent[] { EditorGUIUtility.TextContent("NavmeshEditor.ObjectSettings"), EditorGUIUtility.TextContent("NavmeshEditor.BakeSettings") };
            public readonly GUIContent m_OffmeshHeader = new GUIContent("Generated Off Mesh Links");
            public readonly GUIContent m_WidthInaccuracyContent = EditorGUIUtility.TextContent("NavMeshEditorWindow.WidthInaccuracy");
        }
    }
}

